<!--
 * @Author      : fengshan@0525 3183359488@qq.com
 * @Date        : 2023-02-28 14: 09: 50
 * @LastEditors: asanupup 15465106+asanupup@user.noreply.gitee.com
 * @LastEditTime: 2025-07-22 17:00:37
 * @FilePath    : \vbase2\src\components\MyTable\index.vue
 * @Description : table表格封装，使用该表格组件可快速创建90%的业务表格
 * options 选项：
   border（Boolean）、
   stripe     : （Boolean）、
   showPagination: 是否显示分页、默认显示
   showSelect是否可选择, 默认不选择
   showOrder  : Boolean 是否显示排序， 默认显示
   showOption : Booean 是否显示操作，默认显示
   optionWidth: 操作项宽度，默认250, 可不用加'px'
   height  : 表格最大高度
   expandRow  : 展开行
   rowSelectable: Boolean 是否支持选中行
   fixedColumn: Boolean 是否固定列选中项目、序号

 * tableColumns 选项：
   slotable(Boolean,父组件：<template v-slot:prop=${row}>, 其中prop就是tableColumns中的prop, 使用了slotable就必须要设置相应的插槽！)、
   showOverflowTooltip(Boolean)、
   headtooltip：Boolean控制是否需要提示文案如果设置为true，则需要传入tooltipContent：'12333'、
   sortable：Boolean，是否可排序，设置为true，则需要@sortChange = "handleSortChange"来接受emit事件, 注意根据需要调整order，比如可调整为0 | 1 | false | true 等等
   width         : 宽度, 默认180px
 * tableOutHeader: 表格外头部插槽
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->

<!--
  Copyright@ UKDQ
  Author@ Fengshan
  Time: 2024-9-19
  :height="options.height"
-->
<template>
  <div>
    <slot name="tableOutHeader"></slot>
    <el-table
      :data="props.tableData"
      :row-key="getRowKey"
      v-loading="props.tableLoading"
      class="mt-3 w-100"
      @selection-change="(val) => emit('selectionChange', val)"
      @select-all="(val) => emit('selectionAll', val)"
      @sort-change="(val) => emit('sortChange', val)"
      :stripe="props.options.stripe !== undefined ? props.options.stripe : true"
      :height="props.options.height ? props.options.height : null"
      :highlight-current-row="props.options.rowSelectable"
      @current-change="(val) => emit('selectedRow', val)"
      :ref="baseTableRef"
    >
      <el-table-column v-if="props.options.expandRow" type="expand" fixed="left">
        <template v-slot="{ row }">
          <slot name="expandRow" :row="row"></slot>
        </template>
      </el-table-column>
      <el-table-column v-if="props.options.showSelect" label="#" type="selection"  fixed="left"></el-table-column>
      <el-table-column label="序号" prop="index" type="index"  fixed="left" width="55" v-if="props.options.showOrder !== undefined ? props.options.showOrder : true"></el-table-column>

      <TableColumn v-for="item in props.tableColumns" :key="item.prop" :item="item">
        <template v-if="item.slotable" v-slot:[item.prop]="{ row }">
          <slot :row="row" :name="item.prop"></slot>
        </template>
      </TableColumn>

      <el-table-column label="操作" :width="props.options.optionWidth ? props.options.optionWidth : '180'" fixed="right" v-if="props.options.showOption !== undefined ? props.options.showOption : true">
        <template v-slot="{ row }">
          <slot :row="row" name="operation"></slot>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      v-if="props.options.showPagination !== undefined ? props.options.showPagination : true"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="props.pageNum"
      :page-sizes="props.pageSizes"
      :page-size="props.pageSize"
      :layout="props.layout"
      :total="props.total"
    >
    </el-pagination>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
// @ts-ignore
import TableColumn from './TableColumn.vue'
import { uniqueId } from 'lodash-es'

/**
 * @brief: 表格组件属性定义
 */
interface Props {
  tableData: any[]
  tableColumns: any[]
  tableLoading?: boolean
  pageSizes?: number[]
  pageSize?: number
  pageNum?: number
  total?: number
  options?: any
  layout?: string
}

/**
 * @brief: 组件属性，设置默认值
 */
const props = withDefaults(defineProps<Props>(), {
  tableData: () => [],
  tableColumns: () => [],
  tableLoading: false,
  pageSizes: () => [20, 40, 60, 100],
  pageSize: 20,
  pageNum: 1,
  total: 0,
  options: () => ({}),
  layout: 'total, sizes, prev, pager, next, jumper'
})

/**
 * @brief: 定义组件事件
 */
const emit = defineEmits([
  'selectionChange',
  'selectionAll',
  'sortChange',
  'selectedRow',
  'update:pageNum',
  'update:pageSize',
  'turnOn'
])

// 响应式数据
const baseTableRef = ref(uniqueId())

/**
 * @brief: 获取行的唯一key
 * @param {any} row 行数据
 * @return {any} 返回唯一标识
 */
const getRowKey = (row: any) => {
  // 为嵌套数据提供唯一的row-key
  if (row.id !== undefined) {
    return row.id
  }
  if (row.recog_type !== undefined) {
    return row.recog_type
  }
  if (row.algo_no !== undefined) {
    return row.algo_no
  }
  if (row.index !== undefined) {
    return row.index
  }
  // 兜底方案：使用对象的内存地址
  return row
}

/**
 * @brief: 处理当前页变化
 * @param {number} value 新的页码
 */
const handleCurrentChange = (value: number) => {
  emit('update:pageNum', value)
  emit('turnOn')
}

/**
 * @brief: 处理每页大小变化
 * @param {number} value 新的每页大小
 */
const handleSizeChange = (value: number) => {
  emit('update:pageSize', value)
  emit('turnOn')
}

/**
 * @brief: 重新布局表格
 */
const doLayout = () => {
  console.log('doLayout')
  // 这里需要通过ref访问表格实例
}
</script>
<style scoped>
.el-pagination {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

.mt-3 {
  margin-top: 12px;
}

.w-100 {
  width: 100%;
}
</style>
